package com.gopay.bis.service.bank.payconfig;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.gopay.bis.dao.payconfig.BisBankBizIntrConfigDAO;
import com.gopay.bis.dao.payconfig.BisBankBizSpTranConfigDAO;
import com.gopay.bis.dao.payconfig.BisBizProdSpBankConfigDAO;
import com.gopay.bis.dao.payconfig.BisBizProdSpTranBKConfigDAO;
import com.gopay.bis.manager.bank.payconfig.BisBankExtConfigManager;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.dao.bank.BisBankBusProdDAO;
import com.gopay.common.domain.bank.payconfig.bo.PayConfigInfo;
import com.gopay.common.domain.bis.BaseBisBankConfig;
import com.gopay.common.domain.bis.BisBankBizIntrConfig;
import com.gopay.common.domain.bis.BisBankBizSpTranConfig;
import com.gopay.common.domain.bis.BisBankBusProd;
import com.gopay.common.domain.bis.BisBizProdSpBankConfig;
import com.gopay.common.domain.bis.BisBizProdSpTranBKConfig;

/**
 * 
 * @author liujy
 * 
 */
@Service("payConfigCommonService")
public class PayConfigCommonService {
	
	private static final Logger logger = LoggerFactory.getLogger(PayConfigCommonService.class);
			
	
	// 银行接口通道配置
	@Resource(name = "bisBankExtConfigManager")
    private BisBankExtConfigManager bisBankExtConfigManager;
	
	// 银行交互服务 银行业务产品支持接口通道配置表
	@Resource(name="bisBankBizIntrConfigDAO")
	private BisBankBizIntrConfigDAO bisBankBizIntrConfigDAO;
	// 银行交互服务 银行业务产品支持接口通道配置表
	private Map<String, String> bisBankBussProds = new HashMap<String, String>();	

	
	// 银行业务产品字典表
	@Resource(name="bisBankBusProdDAO")
	private BisBankBusProdDAO bisBankBusProdDAO;
	// 银行业务产品字典
	private Map<String, BisBankBizIntrConfig> bisBankBizIntrConfigs = new HashMap<String, BisBankBizIntrConfig>();		
	
	
	
	
	// 是否初始化银行业务产品支持的交易配置信息
	private boolean isInitBisBankBizSpTranConfigs = true;
	// 银行业务产品支持的交易
	@Resource(name = "bisBankBizSpTranConfigDAO")
	private BisBankBizSpTranConfigDAO bisBankBizSpTranConfigDAO;
	// 银行业务产品支持交易配置信息
	private List<BisBankBizSpTranConfig> bisBankBizSpTranConfigs;

	
	
	
	// 是否初始化银行业务产品支持的银行配置信息
	private boolean isInitBizProdSpBankConfigs = true;
	@Resource(name="bisBizProdSpBankConfigDAO")
	private BisBizProdSpBankConfigDAO bisBizProdSpBankConfigDAO;
	// 银行业务产品支持的银行
	private List<BisBizProdSpBankConfig> bisBizProdSpBankConfigs;
		
	
	
	
	
	// 是否初始化银行业务产品支持的银行配置信息
	private boolean isInitBankBizProdAndTranBankConfigs = true;
	// 业务产品+交易支持的银行
	@Resource(name = "bisBizProdSpTranBKConfigDAO")
	private BisBizProdSpTranBKConfigDAO bisBizProdSpTranBKConfigDAO;
	// 银行业务产品+交易支持的银行码
	private List<BisBizProdSpTranBKConfig> bankBizProdAndTranBankConfigs;
	
	/**
	 * 银行业务产品支持的接口通道
	 * @param chCode
	 * @param bankBussProd
	 * @return
	 */
	public BisBankBizIntrConfig getBisBankBizIntrConfig(String chCode, String bankBussProd){
		logger.info(" chCode = " + chCode + " bankBussProd = " + bankBussProd);
		logger.info(" ----------- print bisBankBizIntrConfigs statrt");
		this.printLog(bisBankBizIntrConfigs);
		logger.info(" ----------- print bisBankBizIntrConfigs end ");
		if(bisBankBizIntrConfigs.isEmpty()){
			synchronized (bisBankBizIntrConfigs) {
				if(bisBankBizIntrConfigs.isEmpty()){
					List<BisBankBizIntrConfig> configs = bisBankBizIntrConfigDAO.findAll();
					if(null == configs || configs.isEmpty()){
						return null;
					}
					for(BisBankBizIntrConfig config : configs){
						bisBankBizIntrConfigs.put(config.getBankBizProdCode() + "-" + config.getIntrChannelCode(), config);
					}
				}
			}
		}
		
		String key = new StringBuilder().append(bankBussProd).append("-").append(chCode).toString();
		return bisBankBizIntrConfigs.get(key);
	}
		
	/**
	 * 暂不用缓存实现
	 * @param bankCode
	 * @param bankBizProd
	 * @return
	 */
	public BaseBisBankConfig getBankInreChanConfigsByBankCodeAndProd(
			String bankCode, BisBankBusinessProd bankBizProd){
		
		BaseBisBankConfig config = null;
		if(BisBankBusinessProd._09.equals(bankBizProd)){
			config = bisBankExtConfigManager.findBcdlIntrConfigByBankCode(bankCode);
		}else{
			config = bisBankExtConfigManager.
					findExtConfigByBankCodeAndBankBusProd(bankBizProd, bankCode);
		}
		return config;
	}
	
	public BaseBisBankConfig getBankInreChanConfigsByBankChannelAndProd(
            String bankCode, BisBankBusinessProd bankBizProd, BisBankInterfaceChannel channel){
        return bisBankExtConfigManager.findExtConfigByBankChannelAndBankBusProd(bankBizProd, channel, bankCode);
    }
	
	public List<BaseBisBankConfig> getAllBcdlIntrConfig() {
		List<BaseBisBankConfig> configs = bisBankExtConfigManager.findAllBcdlIntrConfig();
		return configs;
	}

	public List<BaseBisBankConfig> getAllEbankCustConfig() {
		List<BaseBisBankConfig> configs = bisBankExtConfigManager.findAllEbankCustConfig();
		return configs;
	}
	
	/**
	 * 
	 * @param intTxnCd
	 * @return
	 */
	public List<String> getBankBizProdAndTranBankConfigsByIntTxnCdAndProd(IntTxnCd intTxnCd, String bankBizProd){
		List<String> list = new ArrayList<String>();
		
		if(isInitBankBizProdAndTranBankConfigs){
			isInitBankBizProdAndTranBankConfigs = false;
			initBankBizProdAndTranBankConfigs();
		}
		
		for (int i = 0, size = null == bankBizProdAndTranBankConfigs ? 0
				: bankBizProdAndTranBankConfigs.size(); i < size; i++) {
			BisBizProdSpTranBKConfig config = bankBizProdAndTranBankConfigs.get(i);
			if (null == config || !bankBizProd.equals(config.getBankBizProdCode())
					|| !bankBizProd.equals(config.getBankBizProdCode())) {
				continue;
			}
			list.add(config.getBankCode());
		}
		return list;
	}
	
	/**
	 * 加载 银行业务产品支持银行配置信息
	 */
	private void initBankBizProdAndTranBankConfigs() {
		bankBizProdAndTranBankConfigs = bisBizProdSpTranBKConfigDAO.findAll(); 
	}
	
	
	/**
	 * 
	 * @param intTxnCd
	 * @return
	 */
	public List<String> getBankBizProdBankConfigsByBankBizProd(String bankBizProd){
		List<String> list = new ArrayList<String>();
		
		if(isInitBizProdSpBankConfigs){
//			isInitBizProdSpBankConfigs = false;
			//根据产品类型初始化不同银行配置信息
			if (BisBankBusinessProd._00.value.equals(bankBizProd)) {
				// 个人网银
				bisBizProdSpBankConfigs = bisBizProdSpBankConfigDAO.findEbankB2c(); 
			} else if (BisBankBusinessProd._01.value.equals(bankBizProd)) {
				// 企业网银
				bisBizProdSpBankConfigs = bisBizProdSpBankConfigDAO.findEbankB2b(); 
			} else if (BisBankBusinessProd._05.value.equals(bankBizProd)) {
				// 信用卡快捷
				bisBizProdSpBankConfigs = bisBizProdSpBankConfigDAO.findCreditExpay();
			} else if (BisBankBusinessProd._15.value.equals(bankBizProd)) {
				// 借记卡快捷
				bisBizProdSpBankConfigs = bisBizProdSpBankConfigDAO.findDebitExpay();
			} else {
				initBizProdSpBankConfigs();
			}
		}
		
		for (int i = 0, size = null == bisBizProdSpBankConfigs ? 0
				: bisBizProdSpBankConfigs.size(); i < size; i++) {
			BisBizProdSpBankConfig config = bisBizProdSpBankConfigs.get(i);
			if (null == config || !bankBizProd.equals(config.getBankBizProdCode())) {
				continue;
			}
			list.add(config.getBankCode());
		}
		return list;
	}
	
	/**
	 * 加载 银行业务产品支持银行配置信息
	 */
	private void initBizProdSpBankConfigs() {
		bisBizProdSpBankConfigs = bisBizProdSpBankConfigDAO.findAll(); 
	}

	/**
	 * 交易支持银行产品代码
	 * @param intTxnCd
	 * @return
	 */
	public List<PayConfigInfo> getPayConfigInfosByIntTxnCd(IntTxnCd intTxnCd) {

		List<PayConfigInfo> list = new ArrayList<PayConfigInfo>();
		
		if(isInitBisBankBizSpTranConfigs){
			isInitBisBankBizSpTranConfigs = false;
			initBisBankBizSpTranConfigs();
		}
		
		for (int i = 0, size = null == bisBankBizSpTranConfigs ? 0
				: bisBankBizSpTranConfigs.size(); i < size; i++) {
			BisBankBizSpTranConfig config = bisBankBizSpTranConfigs.get(i);
			if (null == config || !intTxnCd.value.equals(config.getGopayIntTxnCd())) {
				continue;
			}
			PayConfigInfo c = new PayConfigInfo();
			c.setBankBizProd(config.getBankBizProdCode());
			c.setBankBizName(bisBankBussProds.get(config.getBankBizProdCode()));
			c.setIntTxnCd(intTxnCd.value);
			list.add(c);
		}

		return list;
	}
	
	/**
	 * 加载 银行业务产品支持交易配置信息
	 */
	private void initBisBankBizSpTranConfigs(){
		bisBankBizSpTranConfigs = bisBankBizSpTranConfigDAO.findAll();
	}
	
	
	@PostConstruct
	public void initDicParam(){
		logger.info("initDicParam...start");
		List<BisBankBusProd> bankbusps = bisBankBusProdDAO.findAll();
		for(int i = 0, size = null == bankbusps ? 0 : bankbusps.size(); i < size; i++){
			BisBankBusProd prod = bankbusps.get(i);
			if(null == prod){
				continue;
			}
			bisBankBussProds.put(prod.getBankProdCode(), prod.getBankProdName());
		}
		logger.info("initDicParam...end");
	}
	
	@PreDestroy
	public void destroy(){
		logger.info("destroy...");
	}

	
	public void repeatInitBisBankBizSpTranConfigs() {
		logger.info("repeatInitBisBankBizSpTranConfigs...");
		isInitBisBankBizSpTranConfigs = true;
	}
	
	public void repeatInitBankBizProdAndTranBankConfigs() {
		logger.info("repeatInitBankBizProdAndTranBankConfigs...");
		isInitBankBizProdAndTranBankConfigs = true;
	}

	public void repeatInitBizProdSpBankConfigs() {
		logger.info("repeatInitBizProdSpBankConfigs...");
		isInitBizProdSpBankConfigs = true;
	}

	
	
	private void printLog(Map map) {
		Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet()
				.iterator();
		while (entries.hasNext()) {
			Map.Entry<Integer, Integer> entry = entries.next();
			logger.info(" Key = " + entry.getKey() + ", Value = "
					+ entry.getValue());
		}
	}
	
	
	
	
}